/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package za.co.sbi.sbiexam.service;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author sparkyspider
 */
public class Session {

	private long id = 0;
	private long userId = 0;
	private String sessionKey = null;
	private int accessLevelId = 0;
	private Date expiryDate = null;
	private long examkeyId = 0;
	private long writingSessionId = 0;
	private long paperId = 0;
	private User user = null;
	private HashMap<String, String> responseFields = new HashMap();
	private String submittedExamkey = null;

	private Session(long id, String sessionKey, long userId, Date expiryDate, int accessLevelId, long examkeyId) {
		this.id = id;
		this.sessionKey = sessionKey;
		this.userId = userId;
		this.expiryDate = expiryDate;
		this.accessLevelId = accessLevelId;
		this.examkeyId = examkeyId;
	}

	public static Session createSessionFromCookie(HttpServletRequest request) throws SQLException, ClassNotFoundException {

		Session session = null;

		Cookie[] cookies = request.getCookies();
		Cookie sessionCookie = null;

		if (cookies != null) {

		for (Cookie cookie : cookies) {
			if (cookie.getName().equals("sessionKey")) {
				sessionCookie = cookie;
				break;
			}
		}
		}

		if (sessionCookie != null) {
			String sessionKey = sessionCookie.getValue();
			session = getSessionFromDB(sessionKey);
		}

		return session;
	}

	public static Session createNewSession() throws ClassNotFoundException, SQLException {
		String sessionKey = Long.toHexString(System.currentTimeMillis());
		int rowsAffected = DatabaseHelper.update("INSERT INTO session (`sessionKey`, `expiryDate`, `accessLevelId`) VALUES ('" + sessionKey + "', DATE_ADD(NOW(), INTERVAL 36 HOUR), 1)");
		return getSessionFromDB(sessionKey);
	}

	private static Session getSessionFromDB(String sessionKey) throws ClassNotFoundException, SQLException {
		Session session = null;
		ResultSet rs = null;
		try {
			int rowsAffected = DatabaseHelper.delete("DELETE FROM `session` WHERE expiryDate < now()");
			rs = DatabaseHelper.select("SELECT * FROM `session` WHERE `sessionKey` = '" + sessionKey + "'");
			while (rs.next()) {
				session = new Session(rs.getLong("id"), sessionKey.trim(), rs.getLong("userId"), rs.getDate("expiryDate"), rs.getInt("accessLevelId"), rs.getLong("examKeyId"));
			}
			rs.close();
		} catch (SQLException sqlex) {
			if (rs != null) {
				rs.close();
			}
			throw sqlex;
		}
		return session;
	}

	public Cookie getResponseCookie() {
		Cookie cookie = new Cookie("sessionKey", this.getSessionKey());
		cookie.setMaxAge(36 * 3600);
		return cookie;
	}


	public boolean authenticate(String examkey) throws SQLException, ClassNotFoundException {
		ResultSet rs = null;
		boolean authenticated = false;
		submittedExamkey = examkey;

		if (examkey == null) return false;

		try {
			String sql = "SELECT * FROM `examkey` k INNER JOIN `user` u ON k.userId = u.id WHERE used != 1 AND (expires = 0 OR (expires = 1 AND expiryDate > now())) AND `examkey` = '" + examkey.trim() + "'";
			rs = DatabaseHelper.select(sql);
			while (rs.next()) {
				this.userId = rs.getLong("userId");
				this.writingSessionId = rs.getLong("writingSessionId");
				this.paperId = rs.getLong("paperId");
				this.examkeyId = rs.getLong("id");
				authenticated = true;
				break;
			}
			rs.close();
		} catch (SQLException sqlex) {
			if (rs != null) {
				rs.close();
			}
			throw sqlex;
		}

		if (authenticated && userId > 0) {
			this.user = User.loadUser(userId);
		}

		return authenticated;
	}

	public void addResponseField (String key, String value) {
		responseFields.put(key, value);
	}

	public boolean authenticate(String username, String password) {
		return false;
	}
	
	public int getAccessLevelId() {
		return accessLevelId;
	}

	public long getExamkeyId() {
		return examkeyId;
	}

	public Date getExpiryDate() {
		return expiryDate;
	}

	public long getId() {
		return id;
	}

	public long getPaperId() {
		return paperId;
	}

	public String getSessionKey() {
		return sessionKey;
	}

	public User getUser() {
		return user;
	}

	public long getWritingSessionId() {
		return writingSessionId;
	}

	public HashMap getResponseFields() {
		return responseFields;
	}

	public String getSubmittedExamkey() {
		return submittedExamkey;
	}

	void update(User user) throws SQLException, ClassNotFoundException {
		if (user != null) {
			DatabaseHelper.update("UPDATE `session` SET `userId`=" + user.getUserId() + ", `accessLevelId`=" + user.getAccessLevelId() + ", `examkeyId`=" + this.getExamkeyId() + " WHERE `sessionKey`='" + this.getSessionKey() + "'");
		}
	}

}
